/**********************************************************************************
 * Code license:  GNU General Public License v3                                   *
 * Main page:     https://code.google.com/p/library-cross-platform/               *
 * Issue tracker: https://code.google.com/p/library-cross-platform/issues/list    *
***********************************************************************************/

package library.util;

import java.util.*;

@SuppressWarnings({"rawtypes", "unchecked"})
public class ArrayContainer 
{
  protected              List      listLink;
  protected static final int       default_container_size    = 1000;
  
  public ArrayContainer(int initialCapacity) {
    listLink = new ArrayList(initialCapacity);
  }

  public ArrayContainer() {
    this(default_container_size);
  }
  
  /********************************************************
   Add new list data
  *********************************************************/
  public void addContainer(List l) {
    listLink.add(l);
  }
  
  /********************************************************
   Get column data.
  return: List
  *********************************************************/
  public List getContainer(int index) {
    return (List)listLink.get(index);
  }
  
  /********************************************************
   Get size of array
  *********************************************************/
  public int size() {
   int return_size = 0;
   int link_list_size = listLink.size();
   for(int i = 0; i < link_list_size; i++) {
     return_size +=  ((List)listLink.get(i)).size();
   }
   return return_size;
  }
  
  /********************************************************
   Used if size of all columns is not identical
   Return reference to Object
  *********************************************************/
  public Object get(int index) {
    int counter = 0;
    int linked_list_size = listLink.size();
    Object retObject = null;
    List   list_data;
    
    for(int icount = 0; icount < linked_list_size; icount ++) {
      list_data = (List)listLink.get(icount);
      counter = list_data.size();
      if(counter <= index) {
        index -= counter;
        continue;
      }
      else {
        retObject = list_data.get(index);
        break;
      }    	  
    }
    return retObject;
  }
  
  /********************************************************
   Used if size of all columns is identical
   if size of all columns is identical.
   time to get element is minimum.
   Return reference to Object
  ********************************************************/
  public Object getElementMatrix(int index) {
    int linked_list_size = listLink.size();
    int column_id = index / linked_list_size;
    int element_in_column = index - (column_id*linked_list_size);
    List  list_data = (List)listLink.get(column_id);
    return list_data.get(element_in_column);
  }
  
  /********************************************************
   Replace exixting element by new element
  ********************************************************/
  public void set(int index, Object element) {
    int counter = 0;
    int linked_list_size = listLink.size();
    List   list_data;
	    
    for(int icount = 0; icount < linked_list_size; icount ++) {
      list_data = (List)listLink.get(icount);
      counter = list_data.size();
      if(counter <= index) {
        index -= counter;
        continue;
      }
      else {
        list_data.set(index, element);
        break;
      }
    }
  }

  /********************************************************
   Add new element to the array.
    note: new column size will not identical. function
    getElementMatrix(...) should not be used.
  ********************************************************/
  public void add(int index, Object element) {
    int counter = 0;
    int linked_list_size = listLink.size();
    List   list_data;
		    
    for(int icount = 0; icount < linked_list_size; icount ++) {
      list_data = (List)listLink.get(icount);
      counter = list_data.size();
      if(counter <= index) {
        index -= counter;
        continue;
      }
      else {
        list_data.add(index, element);
        break;
      }
    }
  }

}
